package com.kamistoat.meimeistore.order.listener;


import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.kamistoat.common.runTimeFunc.RunTimeLog;
import com.kamistoat.meimeistore.order.config.AlipayTemplate;
import com.kamistoat.meimeistore.order.service.OrderService;
import com.kamistoat.meimeistore.order.vo.PayAsyncVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class OrderPayedListener {

    @Autowired
    OrderService orderService;
    @Autowired
    AlipayTemplate alipayTemplate;

    /**
     * 收到支付宝异步通知，返回success
     *
     * @return
     */
    @PostMapping("/payed/notify")
    public String handleAlipayed(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException, ParseException {
        System.out.println("收到支付宝异步通知==>");
        // 验证签名
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号

        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号

        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

        // 交易金额
        String buyer_pay_amount = new String(request.getParameter("buyer_pay_amount").getBytes("ISO-8859-1"), "UTF-8");

        // 交易时间
        String notify_time_string = new String(request.getParameter("notify_time").getBytes("ISO-8859-1"), "UTF-8");
        DateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date notify_time = dataFormat.parse(notify_time_string);

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(
                params,
                alipayTemplate.getAlipay_public_key(),
                alipayTemplate.getCharset(),
                alipayTemplate.getSign_type());

        if (verify_result) {//验证成功
            //////////////////////////////////////////////////////////////////////////////////////////

            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
            //out.clear();
            //out.println("success");    //请不要修改或删除
            System.out.println("签名验证成功");
            PayAsyncVo payAsyncVo = new PayAsyncVo();
            payAsyncVo.setTrade_no(trade_no);
            payAsyncVo.setOut_trade_no(out_trade_no);
            payAsyncVo.setTrade_status(trade_status);
            payAsyncVo.setNotify_time(notify_time);
            payAsyncVo.setTotal_amount(buyer_pay_amount);
            String result = orderService.handlePayedNotify(payAsyncVo);
            return result;
            //////////////////////////////////////////////////////////////////////////////////////////
        } else {//验证失败
            //out.println("fail");
            System.out.println("签名验证失败");
            return "fail";
        }
    }


    /**
     * 绕过真实支付，该响应直接认为接收到支付成功回调。注意，此处不进行任何幂等性验证，因为在之前必须已经确保幂等性，
     *
     * @return
     */
    @GetMapping("/payed/notify-prod")
    public String handlePayedPord(@RequestParam String orderSn, @RequestParam String payment, HttpServletRequest httpServletRequest) {
        RunTimeLog.printRunTimeLog("接收到支付成功回调");
        PayAsyncVo payAsyncVo = new PayAsyncVo();
        String trade_no = "prod_" + UUID.randomUUID().toString();
        payAsyncVo.setTrade_no(trade_no);
        payAsyncVo.setOut_trade_no(orderSn);
        payAsyncVo.setTrade_status("TRADE_SUCCESS");
        payAsyncVo.setNotify_time(new Date());
        payAsyncVo.setTotal_amount(payment);
        payAsyncVo.setSubject("模拟支付接口");
        String result = orderService.handlePayedNotify(payAsyncVo);

        String redirectPath = "";

        // 如果支付信息入库时出现错误，应该不断重试，在重试一定次数后仍然出错，触发退款程序
        if(result.equals("success")){
            String message = "支付成功，订单编号:" + orderSn;
            httpServletRequest.getSession().setAttribute("orderCheckMsg", message);
            redirectPath = "redirect:http://order.meimeistore.com/orderlist.html";
        }else{
            redirectPath = "redirect:http://order.meimeistore.com/payed/notify-prod?orderSn="
                    + orderSn + "&payment=" + payment;
        }
        return redirectPath;
    }
}
